package com.cslg.questionnaires.service;

import com.cslg.questionnaires.mapper.QuestionFormMapper;
import com.cslg.questionnaires.mapper.QuestionMapper;
import com.cslg.questionnaires.mapper.StudentMapper;
import com.cslg.questionnaires.utils.QuestionFormUtils;
import com.cslg.questionnaires.utils.QuestionUtils;
import com.cslg.questionnaires.utils.ServiceMessageBuilder;
import com.qianxinyao.analysis.jieba.keyword.Keyword;
import com.qianxinyao.analysis.jieba.keyword.TFIDFAnalyzer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.rmi.MarshalledObject;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ComputeFormService {
    @Resource
    QuestionMapper questionMapper;
    @Resource
    QuestionFormMapper questionFormMapper;
    @Resource
    StudentMapper studentMapper;

    public HashMap<String,Object> computeForm(int questionId,String userType,int userId){
        // 查询问卷
        Map<String,Object> question = questionMapper.getQuestionById_uType_uId(questionId,userType,userId);
        if (question == null){
            return ServiceMessageBuilder
                    .buildMessage(404,"没有找到该问卷！",null);
        }
        ArrayList questionContent = QuestionUtils.parseQuestionContent((String) question.get("content"));

        // 构造 问题统计器，即每个问题构造一个统计器，向其中填数据
        ArrayList<Map> computeList = new ArrayList<>();
        for (int i = 0;i < questionContent.size();i ++){
            String question_type = (String) ((HashMap) questionContent.get(i)).get("type");
            String question_title = (String) ((HashMap) questionContent.get(i)).get("title");

            // 构建单个问题统计Map
            HashMap<String,Object> oneQuestion = new HashMap<>();
            oneQuestion.put("type",question_type);
            oneQuestion.put("title",question_title);
            switch (question_type){
                case "oneChoose":
                case "moreChoose":
                    String[] content_list = (String[]) ((HashMap) questionContent.get(i)).get("options");
                    ArrayList<Map> amount = new ArrayList<>();
                    for (int j = 0;j < content_list.length;j ++){
                        Map<String,Object> option_count = new HashMap<>();
                        option_count.put("option",(char) (j+65)+"."+content_list[j]);
                        option_count.put("count",0);
                        amount.add(option_count);
                    }
                    oneQuestion.put("amount",amount);
                    break;
                case "oneLineText":
                case "moreLineText":
                    Map<String,Integer> word_count = new HashMap<>();
                    oneQuestion.put("wordsCount",word_count);
                    break;
                case "recommendPerson":
                    HashMap<String,Integer> person_amount = new HashMap<>();
                    ArrayList<Map>  person_details = new ArrayList<>();
                    oneQuestion.put("amount",person_amount);
                    oneQuestion.put("personDetails",person_details);
                    break;
            }
            computeList.add(oneQuestion);
        }

        // 读取对应的问卷表单
        List<Map> questionForms = questionFormMapper.getFormContentByQuestionId(questionId);
        TFIDFAnalyzer tfidfAnalyzer = new TFIDFAnalyzer();
        // 统计问卷表单 数量
        int forms_count = questionForms.size();
        for (int i = 0;i < forms_count;i ++){
            Map<String,Object> oneForm = questionForms.get(i);
            // 表单 内容
            List<HashMap> contents = QuestionFormUtils.parseAnswerContent((String) oneForm.get("content"));
            for (int j = 0;j < contents.size();j ++){
                String type = (String) contents.get(j).get("type");
                switch (type){
                    case "oneChoose":
                        int answer_oneChoose = (int)contents.get(j).get("answer");
                        Map<String,Object> oneChoose = (Map<String, Object>)
                                ((ArrayList)computeList.get(j).get("amount")).get(answer_oneChoose);
                        int oneChoose_count = (int)oneChoose.get("count")+1;
                        oneChoose.put("count",oneChoose_count);
                        break;
                    case "moreChoose":
                        ArrayList<Integer> answers_moreChoose = (ArrayList) contents.get(j).get("answer");
                        for (int answer_moreChoose : answers_moreChoose){
                            Map<String,Object> moreChoose = (Map<String, Object>)
                                    ((ArrayList)computeList.get(j).get("amount")).get(answer_moreChoose);
                            int moreChoose_count = (int)moreChoose.get("count")+1;
                            moreChoose.put("count",moreChoose_count);
                        }
                        break;
                    case "oneLineText":
                    case "moreLineText":
                        String answer = (String) contents.get(j).get("answer");
                        Map<String,Integer> word_count = (Map<String, Integer>)computeList.get(j).get("wordsCount");
                        List<Keyword> keywords =  tfidfAnalyzer.analyze(answer,8);
                        for (Keyword keyword : keywords){
                            if (word_count.containsKey(keyword.getName())){
                                Integer oneword_count = word_count.get(keyword.getName())+1;
                                word_count.put(keyword.getName(),oneword_count);
                            }else {
                                word_count.put(keyword.getName(),1);
                            }
                        }
                        break;
                    case "recommendPerson":
                        // 判断人名是否存在
                        String[] Person_msg = ((String[])contents.get(j).get("answer"));
                        String personMajor = Person_msg[0];
                        String personNum = Person_msg[1];
                        String personName = Person_msg[2];

                        List<Map> personDetails_list = (List<Map>) computeList.get(j).get("personDetails");
                        Map<String,String> onePersonDetails = new HashMap<>();
                        onePersonDetails.put("major_name",personMajor);
                        onePersonDetails.put("stu_id",personNum);
                        onePersonDetails.put("stu_name",personName);
                        personDetails_list.add(onePersonDetails);

                        Map<String,Integer> amount_Person = (Map<String, Integer>) computeList.get(j).get("amount");
                        if (amount_Person.containsKey(personNum+"-"+personName)){
                            int Person_count = amount_Person.get(personNum+"-"+personName)+1;
                            amount_Person.put(personNum+"-"+personName,Person_count);
                        }else {
                            amount_Person.put(personNum+"-"+personName,1);
                        }
                        break;
                }
            }
        }
        question.put("content",computeList);
        Date startdate = (Date) question.get("starttime");
        Date finishdate = (Date) question.get("finishtime");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String starttime = sdf.format(startdate);
        String finishtime = sdf.format(finishdate);

        question.put("starttime",starttime);
        question.put("finishtime",finishtime);
        question.put("formcount",forms_count);
        question.remove("owerid");
        question.remove("owertype");
        question.remove("del");

        List<Map<String,Object>> contents = (List<Map<String, Object>>) question.get("content");
        for(Map<String,Object> oneq : contents){
            if (oneq.get("type").equals("recommendPerson")){
                HashMap<String,Integer> name_count = (HashMap<String, Integer>) oneq.get("amount");
                List<Map.Entry<String,Integer>> list = new ArrayList<>(name_count.entrySet());
                Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
                    @Override
                    public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                        return o2.getValue().compareTo(o1.getValue());
                    }
                });
                if (list.size()>=15){
                    oneq.put("amount",list.subList(0,15));
                }else
                    oneq.put("amount",list);

            }
        }

        /**
         * question:{
         *     id:1,
         *     title:"title",
         *     starttime:"2019-04-10 20:45",
         *     finishtime:"2019-05-15 21:50",
         *     isexamine: 0,
         *     content:[
         *         {
         *             type:"oneChoose/moreChoose",
         *             title:"title_oneChoose",
         *             amount:[
         *                 {
         *                     option:"A.选项",
         *                     count:10
         *                 },
         *                 {
         *                     option:"B.选项",
         *                     count:5
         *                 }
         *             ]
         *         },
         *         {
         *             type:"oneLineText/moreLineText",
         *             title:"title_oneLineText",
         *             wordsCount:{
         *                 "词汇1":10,
         *                 "词汇2":25
         *             }
         *         },
         *         {
         *             type:"recommendPerson",
         *             title:"title_recommendPerson",
         *             amount:[
         *                 {"学号-姓名1":25},
         *                 {"学号-姓名2":10}
         *             ],
         *             personDetails:[{
         *                  "stu_id":"Z09416155"
         *                  "stu_name":"XXX"
         *                  major_name:"软件工程"
         *             }]
         *
         *         }
         *     ]
         * }
         */
        return ServiceMessageBuilder
                .buildMessage(200,"success",question);

    }
}
